home *** CD-ROM | disk | FTP | other *** search
/ NetNews Offline 2 / NetNews Offline Volume 2.iso / news / comp / lang / modula2 / 252 < prev    next >
Encoding:
Text File  |  1996-08-06  |  8.9 KB  |  303 lines

  1. Path: nemeter.dinoco.de!deliah!michely
  2. From: michely@nemeter.dinoco.DE (Joachim Michely)
  3. Newsgroups: comp.lang.modula2
  4. Subject: Re: Reading Floppies.
  5. Distribution: world
  6. Message-ID: <823299076snx@nemeter.dinoco.DE>
  7. References: <1996Feb1.125721.18589@ucl.ac.uk>
  8. Date: Fri, 02 Feb 96 22:11:16 GMT
  9. Organization: CCP Koeln
  10.  
  11. zcaccau@cs.ucl.ac.uk writes in article <1996Feb1.125721.18589@ucl.ac.uk>:
  12. > In modula-2 is there any way that you can determine whether a floppy drive
  13. > currently contains a disk and whether it is correctly formatted,  (i.e.
  14. > whether the drive is readable), without getting the DOS abort, retry or
  15. > ignore message.  I would like this to work with CD's, IOMEGA ZipDrives,
  16. > etc... as well.  I have looked through a list of interrupts, but am unable
  17. > to find one to do this.  I am able to tell whether the drive exists, by
  18. > using the setdrive & getdrive interrupts.
  19.  
  20. This has nothing special to do with Modula, its DOS.
  21. You have to use DOS Interrupts and write an "Critical Error Handler-Int 24h"
  22. to intercept the error code. You can analyse the received error code in
  23. the Int24 Handler. You will receive information about the device - block
  24. ( eg. Diskette or Disk ) or character device ( eg. LPT or COM ) and the type
  25. of operation involved ( eg. read, write ). You can transfer information back
  26. of what to do ( eg. RETRY, ABORT, FAIL, IGNORE ) to DOS.
  27.  
  28. I use it in my own programs.
  29. The following code is for Logitech Modula Vers 3.4. The Multiscope Vers 4.0
  30. compiler needs some changes because identifier names have changed a little
  31. and moved to other modules. But it should be no problem ( Multiscope Vers 4.0
  32. is the Stonybrook compiler with slightly modified Librarys )
  33.  
  34.  
  35. DEFINITION MODULE Int24 ;
  36.  
  37.  
  38. TYPE
  39.   ContCode   = ( ignore , retry , abort , fail ) ;
  40.   DiskOp     = ( read , write ) ;
  41.   DiskPart   = ( dos , fat , dir , data ) ;
  42.   DeviceName = ARRAY [ 0 .. 7 ] OF CHAR ;
  43.   DeviceType = ( block , char ) ;
  44.   Int24Error = ( WriteProtect , UnknownUnit , DriveNotReady ,
  45.                  UnknownCommand , DataError , 
  46.                  BadRequestStructureLen , SeekError ,
  47.                  UnknownMedium , SectorNotFound , 
  48.                  PrinterOutOfPaper , WriteFault , ReadFault ,
  49.                  GeneralFailure ) ;
  50.   ErrorInfo  = RECORD
  51.                  devname  : DeviceName ;
  52.                  CASE devtype : DeviceType OF
  53.                    block : diskop  : DiskOp ;
  54.                            diskloc : DiskPart ;
  55.                  | char  : 
  56.                  END (* CASE *)
  57.                END ; (* RECORD *)
  58.   Int24Proc  = PROCEDURE ( ErrorInfo , Int24Error ) : ContCode ;
  59.  
  60.  
  61. PROCEDURE StartInt24 ( errorproc : Int24Proc ) ;
  62.  
  63. PROCEDURE StopInt24 ;
  64.  
  65. END Int24 .
  66.  
  67.  
  68. IMPLEMENTATION MODULE Int24 ;
  69.  
  70. FROM SYSTEM IMPORT
  71.   SI,BP,
  72.   NEWPROCESS , TRANSFER , IOTRANSFER ,
  73.   PROCESS , ADDRESS ,
  74.   WORD , BYTE , ADR , SIZE ;
  75.  
  76. FROM RTSMain IMPORT
  77.   ProcessDescriptor ;
  78.  
  79. FROM Devices IMPORT
  80.   InstallHandler ,
  81.   SaveInterruptVector ,
  82.   RestoreInterruptVector ;
  83.  
  84. CONST
  85.   Int24  = 24H ;
  86.  
  87. TYPE 
  88.   DeviceBlock    = RECORD 
  89.                      notusedbyus0 : ADDRESS ;
  90.                      notusedbyus1 : BITSET ;
  91.                      notusedbyus2 : WORD ;
  92.                      notusedbyus3 : WORD ;
  93.                      devicename   : DeviceName ;
  94.                    END ;
  95.   ProcessPointer = RECORD
  96.                      CASE BOOLEAN OF
  97.                        TRUE  : Process : PROCESS ;
  98.                      | FALSE : Point   : POINTER TO ProcessDescriptor ;
  99.                      END ;
  100.                    END ;
  101.  
  102.  
  103. VAR
  104.   active       : BOOLEAN ;
  105.   OldVector    : ADDRESS ;
  106.   WorkSpace    : ARRAY [ 0 .. 1000 ] OF BYTE ;
  107.   IntProc      : Int24Proc ;
  108.   Int24Process : PROCESS ;
  109.   Main         : ProcessPointer ;
  110.  
  111.  
  112.  
  113. PROCEDURE StartInt24 ( errorproc : Int24Proc ) ;
  114. BEGIN
  115.   IF NOT active THEN
  116.     IntProc := errorproc ; 
  117.     SaveInterruptVector ( Int24 , OldVector ) ;
  118.     active := TRUE ;
  119.     NEWPROCESS ( Int24Service , ADR ( WorkSpace ) ,
  120.                  SIZE ( WorkSpace ) , Int24Process ) ;
  121.     TRANSFER ( Main.Process , Int24Process ) ;
  122.   END ;
  123. END StartInt24 ;
  124.  
  125.  
  126.  
  127.  
  128. PROCEDURE StopInt24 ;
  129. BEGIN
  130.   (*** this functions doesn't work until now.
  131.        subsequent StartInt24 and StopInt24 will
  132.        lead to an abort of the programm with the
  133.        message : ===> too many concurrent I/O processes
  134.        but is no problem : never need to call Start/Stop several times
  135.  
  136.        jm 20-feb-90
  137.   ***)
  138.   IF active THEN
  139.     active := FALSE ;
  140.     RestoreInterruptVector ( Int24 , OldVector ) ;
  141.   END ;
  142. END StopInt24 ;
  143.  
  144.  
  145.  
  146. PROCEDURE Int24Service ;
  147. VAR
  148.   workset : BITSET ;
  149.   info    : ErrorInfo ;
  150.   work    : RECORD
  151.               CASE BOOLEAN OF 
  152.                 TRUE  : adr   : ADDRESS ;
  153.               | FALSE : point : POINTER TO DeviceBlock
  154.               END ;
  155.             END ;
  156.  
  157.  
  158. BEGIN
  159.   InstallHandler ( Int24Process , Int24 ) ;
  160.   LOOP
  161.     IOTRANSFER ( Int24Process , Main.Process , Int24 ) ;
  162.     workset := BITSET ( Main.Point^.topStack^.AX ) ;
  163.     WITH Main.Point^ DO
  164.       work.adr.OFFSET  := SI ;
  165.       work.adr.SEGMENT := BP ;
  166.     END ;
  167.     WITH info DO
  168.       IF 15 IN workset THEN
  169.         devtype := char ;
  170.         devname := work.point^.devicename ;
  171.       ELSE
  172.         devtype := block ;
  173.         devname := '  (DISK)' ;
  174.         devname[0] := CHR ( Main.Point^.topStack^.AX MOD 100H + ORD ( 'A' ) ) ;
  175.         IF 8 IN workset THEN
  176.           diskop := write ;
  177.         ELSE
  178.           diskop := read ;
  179.         END ;
  180.         diskloc := VAL ( DiskPart ,
  181.                          ( Main.Point^.topStack^.AX MOD 800H ) DIV 200H ) ;
  182.       END ;
  183.     END ; (* WITH *)
  184.     WITH Main.Point^.topStack^ DO
  185.       AX := ORD ( IntProc ( info , VAL ( Int24Error , DI MOD 10H ) ) ) ;
  186.     END ; (* WITH *)
  187.   END ; (* LOOP *)
  188. END Int24Service ;
  189.  
  190.  
  191. BEGIN
  192.  
  193.   active := FALSE ;
  194.  
  195. END Int24 .
  196.  
  197.  
  198.  
  199.  
  200.  
  201. Example Handler - located in application
  202.  
  203.  
  204. FROM Int24 IMPORT
  205.   ContCode , DiskPart ,  DiskOp ,
  206.   DeviceType , Int24Error ,
  207.   ErrorInfo ,  StartInt24 ;
  208.  
  209.  
  210.  
  211.  
  212.   PROCEDURE ErrorHandler ( Info : ErrorInfo ; Error : Int24Error ) : ContCode ;
  213.   VAR
  214.     return : ContCode ;
  215.     str    : ARRAY [ 0 .. 4 ] OF CHAR ;
  216.   BEGIN
  217.  
  218.     Sounds.Sound ( 4000 ) ;
  219.     CASE Info.devtype OF
  220.       block :
  221.         (*                       1    1    2    2    3    3    4    4    5  *)
  222.         (*             0....5....0....5....0....5....0....5....0....5....0  *)
  223.         Cursor ( 10 , 20 ) ;
  224.         WriteString ( ' Fehler bei Zugriff auf Diskette ' ) ;
  225.         Cursor ( 10 , 21 ) ;
  226.         WriteString ( ' Name : ' ) ;
  227.         WriteString ( Info.devname ) ;
  228.         CASE Info.diskop OF
  229.           read  : WriteString ( ' during read of ' ) ;
  230.         | write : WriteString ( ' during write of ' ) ;
  231.         END ;
  232.         CASE Info.diskloc OF
  233.           dos  : WriteString ( ' DOS' ) ;
  234.         | fat  : WriteString ( ' FAT' ) ;
  235.         | dir  : WriteString ( ' DIR' ) ;
  236.         | data : WriteString ( ' DATA' ) ;
  237.         END ;
  238.         Cursor ( 10 , 22 ) ;
  239.         CASE Error OF
  240.           WriteProtect      : WriteString ( ' Entferne Schreibschutz' ) ;
  241.         | DriveNotReady     : WriteString ( ' Lege Diskette ein und Schließe Klappe' ) ; 
  242.         | DataError         : WriteString ( ' Schlechte Diskette, probiere andere' ) ;
  243.         ELSE
  244.           WriteString ( ' Fehler # : ' ) ;
  245.           CardToString ( ORD ( Error ) , str , 3 ) ;
  246.           WriteString ( str ) ;
  247.         END ; (* CASE *)
  248.         return := retry ; 
  249.     | char :
  250.         (*                       1    1    2    2    3    3    4    4    5  *)
  251.         (*             0....5....0....5....0....5....0....5....0....5....0  *)
  252.         Cursor ( 10 , 20 ) ;
  253.         WriteString ( ' Fehler bei Zugriff auf Printer ' ) ;
  254.         WriteString ( ' Name : ' ) ;
  255.         Cursor ( 10 , 21 ) ;
  256.         WriteString ( Info.devname ) ;
  257.         Cursor ( 10 , 22 ) ;
  258.         CASE Error OF
  259.           DriveNotReady     : WriteString ( ' Drucker ausgeschaltet' ) ; 
  260.         | PrinterOutOfPaper : WriteString ( ' Kein Papier in Drucker' ) ;
  261.         | WriteFault        : WriteString ( ' Drucker ist nicht bereit' ) ;
  262.         ELSE
  263.           WriteString ( ' Fehler # : ' ) ;
  264.           CardToString ( ORD ( Error ) , str , 3 ) ;
  265.           WriteString ( str ) ;
  266.         END ; (* CASE *)
  267.         return := fail ;
  268.     END ; (* CASE devtype OF *)
  269.     Delay.Delay ( 1000 ) ;
  270.     Sounds.NoSound ;
  271.     RETURN return ;
  272.   END ErrorHandler ;
  273.  
  274.  
  275. In the first lines of the main body write :
  276.  
  277.   StartInt24 ( ErrorHandler ) ;
  278.  
  279. Cursor and WriteString position the cursor an the screen and write to the
  280. screen. In "ErrorHandler" don∩t use any DOS Interrupt ( but you can write
  281. to screen ) because DOS isn∩t reentrant.
  282.  
  283. This "ErrorHandler" handles not all possible errors, only those I need
  284. in this application.
  285. Any book about DOS programming ( Ray Duncan:Advanced MSDOS .. ) should give
  286. you information about Int24H
  287.  
  288. Hope this helps
  289.  
  290. Joachim
  291.  
  292. > Any help would be appreciated.
  293. > Chris
  294. Joachim Michely, Steinkaule 50, 53757 St-Augustin, Germany
  295. Voice/Fax  : ++49-(0)2241-337938 ( and answering machine )
  296. Internet   : michely@nemeter.dinoco.DE
  297. CompuServe : 100024,2476
  298.